package org.jvm.rtda.heap.classLoader;

import org.jvm.rtda.Object;
import org.jvm.rtda.heap.*;
import org.jvm.rtda.heap.classmember.Method;
import org.jvm.rtda.heap.stringpool.StringPool;
import org.jvm.rtda.thread.Thread;
import org.jvm.util.JavaCallUtil;

import java.util.Optional;

/**
 * 包含扩展类加载器和用户类加载器以及其他所有使用Java代码实现的类加载器
 *
 * @author 王思翔
 * @date 2023/3/24
 */
public class JavaKlassLoader extends AbstractKlassLoader {


    public JavaKlassLoader(Object jcl) {
        super(jcl);
    }

    /**
     * 根据类名加载一个类
     * 对于javaClassLoader，使用javaCall进行类加载
     *
     * @param klassName
     * @param thread
     * @return
     */
    @Override
    public Klass loadKlass(String klassName, Thread thread) {
        Method loadClassMethod = MethodUtil.lookupMethod(jcl.getKlass(), "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
        String javaClassName = klassName.replace('/', '.');
        Object jString = StringPool.jString(javaClassName);
        //发起javaCall
        Object jClass = (Object) JavaCallUtil.javaCall(thread, loadClassMethod, jcl, jString);
        return (Klass) Optional.ofNullable(jClass).map(Object::getExtra).orElse(null);
    }

    public void addKlass(String name, Klass klass) {
        this.klassMap.put(name, klass);
    }
}
